/*
 * arch/arm/mach-sunxi/include/mach/sunxi-smc.h
 *
 * Copyright(c) 2013-2015 Allwinnertech Co., Ltd. 
 *         http://www.allwinnertech.com
 *
 * Author: sunny <sunny@allwinnertech.com>
 *
 * allwinner sunxi smc functions.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#ifndef __SUNXI_MACH_SMC_H
#define __SUNXI_MACH_SMC_H

#include <linux/io.h>
#include <mach/sunxi-chip.h>
#include <asm/firmware.h>

/* sunxi platform smc commands */
#define TE_SMC_READ_REG                 (0xFFFF0000)
#define TE_SMC_WRITE_REG                (0xFFFF0001)
#define TE_SMC_CPU_POWERUP              (0xFFFF0002)
#define TE_SMC_CPU_POWERDOWN            (0xFFFF0003)
#define TE_SMC_CLUSTER_POWERUP          (0xFFFF0004)
#define TE_SMC_CLUSTER_POWERDOWN        (0xFFFF0005)
#define TE_SMC_LOAD_ARISC               (0xFFFF0006)
#define TE_SMC_SET_SMP_BOOTENTRY        (0xFFFF0007)
#define TE_SMC_GET_DRM_MEM_INFO         (0xFFFF0008)
#define TE_SMC_SUSPEND_PAREPER		(0xFFFF0009)

#define TE_SMC_STANDBY_STATUS_CLEAR	(0xFFFF0010)
#define TE_SMC_STANDBY_STATUS_SET	(0xFFFF0011)
#define TE_SMC_STANDBY_STATUS_GET	(0xFFFF0012)
#define TE_SMC_CP15_STATUS_GET	(0xFFFF0013)

#define TE_SMC_EFUSE_WRITE_REG         (0xFFFF000A)
#define TE_SMC_EFUSE_READ_REG          (0xFFFF000B)
#define TE_SMC_AES_BSSK_EN_TO_DRAM     (0xFFFF000C)
#define TE_SMC_AES_BSSK_DE_TO_KEYSRAM  (0xFFFF000D)

struct smc_param {
	u32 a0;
	u32 a1;
	u32 a2;
	u32 a3;
};
/*raw smc all in asm*/
u32 __sunxi_smc_call(struct smc_param *param); 
u32 __sunxi_fast_smc_call(struct smc_param *param); 

/*generic smc api cpu 0*/
u32 sunxi_smc_call(struct smc_param *param);


#if  defined(CONFIG_SUNXI_TRUSTZONE)
static inline u32 sunxi_smc_readl(void __iomem *addr)
{
	if (sunxi_soc_is_secure()) {
		return call_firmware_op(read_reg, addr);
	} else {
		return readl(addr);
	}
	
}
static inline void sunxi_smc_writel(u32 val, void __iomem *addr)
{
	if (sunxi_soc_is_secure()) {
		call_firmware_op(write_reg, val, addr);
	} else {
		writel(val, addr);
	}
}
#else
static inline u32 sunxi_smc_readl(void __iomem *addr)
{
	return readl(addr);	
}
static inline void sunxi_smc_writel(u32 val, void __iomem *addr)
{
	writel(val, addr);
}
#endif

#endif /* __SUNXI_MACH_SMC_H */
